package telex;
/*
 * IQFNGramDatabase.java
 *
 * Copyright (c) 2007-2008 Colin Bayer, Douglas Downey, Oren Etzioni,
 *   University of Washington Computer Science and Engineering
 * 
 * See the file "COPYING" in the root directory of this distribution for
 * full licensing information.
 */

import java.io.*;
import java.util.HashMap;

public class IQFNGramDatabase extends NGramDatabase {
	public IQFNGramDatabase(String aCountPath) throws IOException, FileNotFoundException {
		mCountPath = aCountPath;
		
		mQueries = new HashMap<QueryString, Query>();
		mMaxArity = 0;
	}
	
	public String getLocation() { return mCountPath; }

	private boolean loadCounts() {
		File f = new File(mCountPath + "/counts.txt");
		
		mCounts = new long[mMaxArity + 1][];
		
		try {		
			if (f.exists()) {
				// load counts from file.
				FileReader fr = new FileReader(f);
				BufferedReader r = new BufferedReader(fr);

				for (int i = 1; i <= mMaxArity; i++) {
					mCounts[i] = new long[2];
					
					String l = r.readLine();
					
					if (l == null) { throw new IOException(); }
					
					String[] w = l.split("\t");
					
					mCounts[i][0] = Long.parseLong(w[0]);
					mCounts[i][1] = Long.parseLong(w[1]);
				}
                fr.close();
				r.close();
			} else throw new FileNotFoundException();
		} catch (Exception e) {
			System.out.println("Failed to load counts: " + e);
			return false;
		}
		
		return true;
	}
	
	public boolean addIQF(IQFReader aIR) throws IOException {
		Query q;
		
		while ((q = aIR.nextQuery()) != null) {
			mQueries.put(q.getQueryString(), q);
			// compute maximum arity by checking each n-gram in turn.
			//System.out.println("Added query [" + q + "] to database, hash code " + q.getQueryString().hashCode());
			mMaxArity = (q.getArity() > mMaxArity) ? q.getArity() : mMaxArity;
		}
		aIR.close();
		
		return true;
	}
	
	public Query executeQuery(Query aQ) {
		if (mCounts == null) {
			if (!loadCounts()) return null;
		}
		
		Query t = mQueries.get(aQ.getQueryString());
		
		//System.out.println("Executed query with hash code " + aQ.getQueryString().hashCode());
		
		if (t == null) {
			System.out.println("query " + aQ.getQueryString().getFlattened() + " failed.");
			return null;
		} else {
			return t;
		}
	}

	public int getMaximumArity() {
		return mMaxArity;
	}

	public long[] getTotalCount(int aArity) {
		if (aArity < 1 || aArity > mMaxArity) return null;
		
		return mCounts[aArity].clone();
	}
	
	private String mCountPath;
	
	private HashMap<QueryString, Query> mQueries;
	private long[][] mCounts;
	private int mMaxArity;
	
	@Override
    public void closeFiles() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}



